﻿using System.Xml.Serialization;
using System.IO;
using System.Xml;
using System.Text;

namespace YunHao
{
    /// <summary>
    /// xml相关的操作
    /// </summary>
    public class XmlControl
    {
        #region Read and Write
        /// <summary>
        /// 读取普通xml文件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path"></param>
        public static T ReadXml<T>(string path)
        {
            string xml = File.ReadAllText(path);
            return XmlDeserialize<T>(xml);
        }

        /// <summary>
        /// 写入普通xml文件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path"></param>
        /// <param name="data"></param>
        public static void WriteXml<T>(string path, T data)
        {
            string xml = XmlSerialize(data);
            File.WriteAllText(path, xml);
        }

        /// <summary>
        /// 读取加密xml文件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path"></param>
        /// <returns></returns>
        public static T ReadCryptoXml<T>(string path)
        {
            string cryptoXml = File.ReadAllText(path);
            string xml = CryptoString.Decrypt(cryptoXml);
            return XmlDeserialize<T>(xml);
        }

        /// <summary>
        /// 加密写入xml文件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path"></param>
        /// <param name="data"></param>
        public static void WriteCryptoXml<T>(string path, T data)
        {
            string xml = XmlSerialize(data);
            string cryptoXml = CryptoString.Encrypt(xml);
            File.WriteAllText(path, cryptoXml);
        }

        #endregion

        #region Async Read

        /// <summary>
        /// 异步读取普通的xml文件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path"></param>
        /// <param name="onFinish"></param>
        /// <param name="onError"></param>
        public static void ReadXmlAsync<T>(string path, System.Action<T> onFinish, System.Action<string> onError)
        {
            ResourceLoadControl.Instance.LoadText(path, (xml) =>
             {
                 onFinish(XmlDeserialize<T>(xml));
             }, onError);
        }

        /// <summary>
        /// 异步读取加密的xml文件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="path"></param>
        /// <param name="onFinish"></param>
        /// <param name="onError"></param>
        public static void ReadCryptoXmlAsync<T>(string path, System.Action<T> onFinish, System.Action<string> onError)
        {
            ResourceLoadControl.Instance.LoadText(path, (cryptoXml) =>
            {
                string xml = CryptoString.Decrypt(cryptoXml);
                onFinish(XmlDeserialize<T>(xml));
            }, onError);
        }

        #endregion

        /// <summary>
        /// Xml序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        public static string XmlSerialize<T>(T data)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                XmlSerializer xmlSer = new XmlSerializer(typeof(T));
                XmlTextWriter xmlWriter = new XmlTextWriter(ms, Encoding.UTF8);
                xmlSer.Serialize(xmlWriter, data);
                UTF8Encoding utf8Encode = new UTF8Encoding();
                return utf8Encode.GetString(ms.ToArray());
            }
        }

        /// <summary>
        /// xml反序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="xmlString"></param>
        /// <returns></returns>
        public static T XmlDeserialize<T>(string xmlString)
        {
            UTF8Encoding utf8Encode = new UTF8Encoding();
            byte[] bytes = utf8Encode.GetBytes(xmlString);
            using (MemoryStream ms = new MemoryStream(bytes))
            {
                XmlSerializer xmlSer = new XmlSerializer(typeof(T));
                return (T)xmlSer.Deserialize(ms);
            }
        }
    }
}